package com.ruoyi.system.config;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
/**
 * 如果消息没有到exchange,则confirm回调,ack=false *
 * 如果消息到达exchange,则confirm回调,ack=true *
 * exchange到queue成功,则不回调return
 *
 * exchange到queue失败,则回调return(需设置mandatory=true,否则不回回调,消息就丢了)
 * 确认方式：
 * 方式一：channel.waitForConfirms( ) 普通发送方确认模式； *
 * 方式二：channel.waitForConfirmsOrDie( ) 批量确认模式； *
 * 方式三：channel.addConfirmListener()异步监听发送方确认模式； *
 * 采用第三种比较好，异步监听
 */
@Component
public class MsgAck {

    @Autowired
    RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init(){
//        rabbitTemplate.setChannelTransacted(true);//设置开启事务
        //消息确认的代码在这里写
        //生产者到交换机的消息确认的代码
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String s) {
                if(ack){
                    //代表生产者的消息已经成功的到达交换机了
                    System.err.println("生产者--->交换机的消息确认成功");
                    //1.

                    //2.
                    //3.
                }else{
                    //否则就没有到达成功
                    String id = correlationData.getId();

                    System.err.println("生产者--->交换机的消息发送不成功");
                }
            }
        });

        //交换机到队列的消息确认的代码
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback(){
            @Override
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                System.err.println("交换机--->队列的消息的路由不成功我就会执行========");
                //1.
                //2.
                //3.
            }
        });
    }
}
